import React, {
  Component,
  createRef,
  createContext,
  useRef,
  useState,
} from "react";
import PropType from "prop-types";
import { BrowserRouter as Router, Routes, Route } from "react-router-dom";
import * as THREE from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
import gsap from "gsap"; //动画库
import Stats from "stats.js"; //性能监控
import { FBXLoader } from "three/examples/jsm/loaders/FBXLoader.js"; // FBX 模型加载器
import { ShaderPass } from 'three/examples/jsm/postprocessing/ShaderPass';
import { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer'; //EffectComposer 效果组合器 它是处理 WebGLRenderer 效果的 接收 renderer为参数
import { RenderPass } from 'three/examples/jsm/postprocessing/RenderPass'; // RenderPass 处理通道 它是处理 scene 场景和相机 camera 的。 接收 scene camera 为参数
import { UnrealBloomPass } from 'three/examples/jsm/postprocessing/UnrealBloomPass';//UnrealBloomPass 泛光通道
import { FXAAShader } from 'three/examples/jsm/shaders/FXAAShader.js'; //添加抗锯齿的效果
import { OutlinePass } from 'three/examples/jsm/postprocessing/OutlinePass'; // 高亮发光描边通道 OutlinePass(画布宽高二维向量，场景scene,相机camera)
import { BloomPass } from 'three/examples/jsm/postprocessing/BloomPass'; // 


// 1、 BufferGeometry 几何体。 以前用addAttribute  现在用 setAttribute 。addAttribute three.js 版本高的 以及废弃，使用 setAttribute
// 2 、 通过顶点着色器和片元着色器，渲染 点以及线条

// 3 、 Three.js提供了RawShaderMaterial和ShaderMaterial两个API用来辅助开发者自定义着色器代码。这个着色器API和其它的three.js的材质对象的基类一样都是Material，会继承基类Material的属性和方法。
// 4  、 RawShaderMaterial和ShaderMaterial 是有区别的 他们的区别在于： 使用ShaderMaterial类，顶点位置变量position无需声明，顶点着色器可以直接调用，  RawShaderMaterial 需要手动声明position
const windowWidth =   window.innerWidth
const windowHeigth = window.innerHeight



const scene = new THREE.Scene(); // 场景
const camera = new THREE.PerspectiveCamera(
  85,
  windowWidth / windowHeigth,
  1,
  1200
); // 相机



const renderer = new THREE.WebGLRenderer({antialias:true}); //渲染器 antialias扛锯齿 默认为false
 const controls = new OrbitControls(camera, renderer.domElement); // 轨道控制器


const axesHelper = new THREE.AxesHelper(500); // 辅助线
scene.add(axesHelper);






const Home = () => {
  //  正常使用 BufferGeometry 基础网格材质 自定义颜色
  const geometry = new THREE.BufferGeometry();
  const vertices = new Float32Array( [
    -1.0, -1.0,  1.0,
     1.0, -1.0,  1.0,
     1.0,  1.0,  1.0,
  
     1.0,  1.0,  1.0,
    -1.0,  1.0,  1.0,
    -1.0, -1.0,  1.0
  ] );
  geometry.setAttribute( 'position', new THREE.BufferAttribute( vertices, 3 ) );
  const material = new THREE.MeshBasicMaterial( { color: 'blue' } );
  const mesh = new THREE.Mesh( geometry, material );
	scene.add( mesh );

  // 使用 BufferGeometry ，用顶点着色器和片元着色器染色
  const geometry1 = new THREE.BufferGeometry();
  const vertices1 = new Float32Array( [
    0.6, 0.2, 0, //顶点1坐标
    0.7, 0.6, 0, //顶点2坐标
    0.8, 0.2, 0, //顶点3坐标
    -0.6, -0.2, 0, //顶点4坐标
    -0.7, -0.6, 0, //顶点5坐标
    -0.8, -0.2, 0, //顶点6坐标
  ] );
  let attribue = new THREE.BufferAttribute(vertices1, 3);
  geometry1.setAttribute( 'position',attribue )
  //  //TODO: 原生着色器材质RawShaderMaterial 必须手动声明position 位置变量 这是它和 ShaderMaterial 区别
  //  const  material1 = new THREE.RawShaderMaterial({
  //   //顶点着色器对象vertexShader
  //   vertexShader:`
  //  attribute vec3 position;
  //   void main(){
  //     // 控制渲染的点大小
  //     gl_PointSize=120.0;
  //     // 逐顶点处理：顶点位置数据赋值给内置变量gl_Position
  //     gl_Position = vec4( position, 1.0 );
  //   }
  //   `,
  //   // 片元着色器对象fragmentShader
  //   fragmentShader:`
  //   void main() {
  //     // 逐片元处理：每个片元或者说像素设置为红色
  //     gl_FragColor = vec4(1.0,0.0,0.0,1.0);
  //  }`,

   //TODO: ShaderMaterial 着色器材质
   const  material1 = new THREE.ShaderMaterial({
    //顶点着色器对象vertexShader
    vertexShader:`
    // attribute vec3 position; ShaderMaterial不需要手动声明这个位置变量，three内部以及处理了 这是它和 RawShaderMaterial 区别
    void main(){
      // 控制渲染的点大小
      gl_PointSize=120.0;
      // 逐顶点处理：顶点位置数据赋值给内置变量gl_Position
      gl_Position = vec4( position, 1.0 );
    }
    `,
    // 片元着色器对象fragmentShader
    fragmentShader:`
    void main() {
      // 逐片元处理：每个片元或者说像素设置为红色
      gl_FragColor = vec4(1.0,0.0,0.0,1.0);
   }`,
  });
  // 创建一个点模型——点渲染模式 或者线 。  new THREE.Points  点 。   new THREE.Line 线

  const point = new THREE.Points(geometry1, material1);
  scene.add(point);

  console.log(scene)

	camera.position.z = 15;

  renderer.setSize(window.innerWidth, window.innerHeight);
  document.body.appendChild(renderer.domElement);
  function animate() {
  
    requestAnimationFrame(animate);
 controls.update();
    renderer.render(scene, camera);
  
  }
  animate();
  return <div></div>;
};

export default Home;
